package com.yangwudi.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

//<----------------------------------该部分为练习内容，与项目无关，可直接删除----------------------------------->


@Slf4j
//@Aspect//标识当前是一个AOP类    -> 切面类
@Component
public class RecordTimeAspect {
    @Around("execution(* com.yangwudi.service.impl.*.*(..))")//匹配所有service包下的所有方法   -> 切入点
    public Object recoedTime(ProceedingJoinPoint pjp) throws Throwable {    // ->通知
        //1. 记录方法运行的开始时间
        long begin = System.currentTimeMillis();

        //2.执行原始的方法
        Object proceed = pjp.proceed();

        //3. 记录方法运行结束的时间
        long end = System.currentTimeMillis();
        log.info("方法{}运行耗时：{}ms", pjp.getSignature()//方法签名
                ,end - begin);
        return proceed;
    }
}

//AOP：面向切面编程 - > 面向特定方法编程
//开发步骤：
//1.引入AOP起步依赖
//2.编写AOP程序（公共的逻辑代码）
//优势：
//1. 减少重复代码
//2. 代码无侵入
//3. 提升开发效率
//4.维护方便
//应用场景：
//记录系统的操作日志
//事务管理
//权限控制
//...


//AOP核心概念：
//1.连接点：Joinpoint,可以被AOP控制的方法
//2.通知：Advice,指那些重复的逻辑，也就是共性功能（最终体现为一个方法）
//3.切入点：Pointcut,匹配连接点的条件，通知仅会在切入点方法执行时被应用
//4.切面：Aspect,描述通知与切入点的对应关系（通知+切入点）
//5.目标对象：Target,通知所应用的对象


//AOP执行流程：Controller -> 代理对象（Proxy） -> 切面逻辑（Around 前置） -> 目标方法（Target Method） -> 切面逻辑（Around 后置） -> Controller
